<template>
	<div>
		<el-form ref="form" :model="form" class="wt-model-form" label-width="100px">
			<el-form-item 
				v-for="(field, index) in fields" 
				v-if="!field.noSave && !field.conditional" 
				:label="field.label" 
				:prop="field.tableName" 
				:key="index" 
				:rules="field.rules">
				<wt-model-field-input
					:ref="field.tableName"
					:field="field"
					:form="form"
					:current-id="currentId"
					:params-data="paramsData"
					:class="{'wt-model-inline-field' : field.conditions}"
					:helpers="helpers"
					@stop="stop"
				></wt-model-field-input>
				<template
					v-for="condition in field.conditions"
					v-if="condition.value == form[field.tableName]"
				>
					<el-form-item
						class="wt-model-inline-field"
						v-for="(conditionalField, index) in condition.fields"
						:prop="conditionalField.tableName"
						:rules="conditionalField.rules"
						:key="index"
					>
						<wt-model-field-input
							class="wt-model-inline-field"
							:field="conditionalField"
							:form="form"
							:current-id="currentId"
							:params-data="paramsData"
							:key="conditionalField.name"
							:helpers="helpers"
						></wt-model-field-input>
					</el-form-item>
					<component 
						class="wt-model-inline-field"
						v-if="condition.appendComponent"
						:is="condition.appendComponent"
						:field="field"
						:form="form"
						:current-id="currentId"
						:params-data="paramsData"
					></component>
				</template>
			</el-form-item>
			<el-form-item>
				<el-button type="primary" @click="onSave" :loading="saving" icon="check">保存</el-button>
				<el-button @click="onCancel" icon="close">取消</el-button>
			</el-form-item>
		</el-form>
	</div>
</template>
<script>

	/**
		数据模型通用表单，根据model配置动态生成表单
	 */
	import Vue from 'vue';
	import ElementUI from 'element-ui';
	import Fields from '../utils/wt-model-field';
	import ModelService from '../utils/wt-model-service';
	import ModelUtils from '../utils/wt-model-utils';
	import TimeUtils from '../utils/wt-time-utils';
	import FormUtils from '../utils/wt-form-utils';
	import FieldInput from './wt-model-field-input';

	Vue.use(ElementUI);
	Vue.component(FieldInput.name, FieldInput);

	export default {
		name: 'wt-model-form',
		props: {
			model: {
				type: Object,
				required: true,
			},
			value: {
				type: Object,
				default: null
			},
			id: {
				type: [Object, String, Number],
				default: null
			},
			paramsData: {
				type: Object,
				default: null
			},
		},
		data() {
			return {
				form: null,
				currentId: this.id,
				saving: false,
				initializing: true,
				/** helpers用于储存一些在字段编辑时可能用到的辅助数据，例如，date字段选择是可通过helpers指定对应的日期选择范围，例如：
				  this.helpers[this.field.tableName] = {
						pickerOptions: {
							disabledDate(time) {
								return time.getTime() < Date.now() - 8.64e7;
							}
						}
					};
				*/
				helpers: {}
			};
		},
		watch: {
			'id'(val, oldValue) {
				if (val === oldValue) return;
				this.currentId = val;
			}
		},
		computed: {
			fields: function() {
				return this.model.fields;
			},
			save: function() {
				return this.model.save;
			},
			types: function() {
				return Fields.types;
			}
		},
		methods: {
			// 加载表单（并不进行重置）
			load() {
				// 检查是否有字段需要重新加载
				for (let i = 0; i < this.model.fields.length; i ++) {
					let field = this.model.fields[i];
					if (field.refreshOnLoad) {
						let ref = this.getFieldRef(field);
						if (ref && ref.load) {
							ref.load();
						}
					}
				}
			},
			getFieldClass(field) {
				return field.formSize ? 'wt-field-' + field.formSize : '';
			},
			// 重置表单为初始数据
			reset() {
				this.form = this.value != null ? ModelUtils.cloneObject(this.value) : ModelUtils.createDefaultObject(this.model);
				ModelUtils.normalizeData(this.model, this.form);
			},
			parseImages(value) {
				if (typeof(value) === 'string') {
					return JSON.parse(value);
				}
				else {
					return [];
				}
			},
			checkReturnData(data) {
				if (data != null) {
					if (this.currentId == null) {
						this.currentId = ModelUtils.getIdValueFromQueryResult(this.model, data);
						this.form[this.model.id_field.name] = this.currentId;
					}
					// 检查其他组件id
					let vm = this;
					// 必须在nextTick之后执行 - 这样子组件能够得到最新变化的currentId
					Vue.nextTick(function() {
						vm.checkFieldsSubmit(function() {
							vm.saveSuccess();
						}, function(field) {
							vm.saving = false;
							vm.$message.error(field.label + '保存失败，请重试');
						}, false);
					});
				}
				else {
					this.$message.error('保存失败');
				}
			},
			getFieldRef(field) {
				let ref = this.$refs[field.tableName];
				if (ref && ref.length > 0) {
					ref = ref[0];
				}
				return ref;
			},
			checkFieldsSubmit(successCallback, errorCallback, preSubmit, index = 0) {
				let fieldToSubmit = null;
				let fieldIndex = index;
				for (let i = index; i < this.model.fields.length; i ++) {
					let field = this.model.fields[i];
					if (field.uploadByComponent && (field.preSubmit || !preSubmit)) {
						fieldToSubmit = field;
						fieldIndex = i;
						break;
					}
				}
				if (fieldToSubmit != null) {
					let ref = this.getFieldRef(fieldToSubmit);
					if (ref) {
						let vm = this;
						ref.submit(function() {
							vm.checkFieldsSubmit(successCallback, errorCallback, preSubmit, fieldIndex + 1);
						}, function() {
							errorCallback(fieldToSubmit);
						})
					}
					else {
						console.error('no component found for field ' + fieldToSubmit.tableName);
					}
				}
				else {
					successCallback();
				}
			},
			onSave() {
				this.doSave();
			},
			onCancel() {
				this.$emit('cancel');
			},
			//中断上传状态，目前用于图片上传大小校验不通过的情况
			stop(){
				this.saving = false;
			},
			saveSuccess() {
				this.saving = false;
				this.$message.success('保存成功');
				this.$emit('saved', this.form);
			},
			doSave(callback) {
				let vm = this;
				let config = null;
				this.$refs.form.validate((valid) => {
					if (valid) {
						if (vm.currentId != null) {
							config = vm.model.update;
						}
						else {
							config = vm.model.new;
						}
						vm.saving = true;
						// 检查有没有要在save之前进行的字段上传
						vm.checkFieldsSubmit(function() {
							ModelUtils.buildQueryExtraParams(config, vm.paramsData, vm.form);
							ModelService.save(vm.model, vm.currentId, vm.form, function(data) {
								data = ModelUtils.parseSingleItemResult(data);
								vm.checkReturnData(data);
							}, function(error) {
								vm.saving = false;
								console.log(error);
								vm.$message.error('保存失败');
							})
						}, function(field) {
							vm.saving = false;
							vm.$message.error(field.label + '保存失败，请重试');
						}, true);
					}
				});
			},
		},
		created() {
			this.reset();
		}
	}

</script>
<style scoped>
.el-form-item__content .wt-model-inline-field {
	display: inline-block;
}
</style>